using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Criterion;
using Didsoft.DataAccess.Hibernate;
using Didsoft.DataAccess.Contracts;
using SIOGDE.AccesoDatos.Entidades;
using SIOGDE.AccesoDatos.Contratos;
using Didsoft.Core.Data;
using SIOGDE.AccesoDatos.Entidades.Reportes;


namespace SIOGDE.AccesoDatos.Contexto
{
   public class PersonaAccesoDatos : DataAccessBasic<Persona>, IPersonaAccesoDatos
   {
     public PersonaAccesoDatos()
     {
     }
     
     /// <summary>
     /// Devuelve una lista IList<Persona> con todas las ocurrencias encontradas, en base a filtro.
     /// </summary>
     /// <param name="filtro"></param>
     /// <returns></returns>
     public IList<Persona> BuscarPorFiltro(string filtro)
     {
         var query = Session.CreateQuery(@"from Persona p 
                                           where (p.ApellidoPaterno+' '+p.ApellidoMaterno+' '+p.Nombre1) like :filtro");
         query.SetAnsiString("filtro", "%"+filtro + "%");         
         return query.List<Persona>();

     }

     public IList<Persona> BuscarPorFiltro(string nombres, string apellidoPaterno, string apellidoMaterno)
     {
         var query = Session.CreateQuery(@"from Persona p 
                                           where p.ApellidoPaterno like :apellidoPaterno AND
                                                 p.ApellidoMaterno like :apellidoMaterno AND
                                                 p.Nombre1 like :nombres");
         query.SetAnsiString("apellidoPaterno", "%" + apellidoPaterno + "%");
         query.SetAnsiString("apellidoMaterno", "%" + apellidoMaterno + "%");
         query.SetAnsiString("nombres", "%" + nombres + "%");
         return query.List<Persona>();

     }


     public DataPager<Persona> PaginarPorFiltro(string filtro, int filas, int numPagina)
     {
         int desde = (filas * numPagina);
         string hql = @"from Persona p where p.ApellidoPaterno like :filtro OR
                                           p.ApellidoMaterno like :filtro OR
                                           p.Nombre1 like :filtro";

         return Session.CreateMultiQuery()
                        .Add(Session.CreateQuery(hql + " order by p.ApellidoPaterno").SetMaxResults(filas).SetFirstResult(desde))
                        .Add("select count(p.Id) " + hql)
                        .SetAnsiString("filtro", "%" + filtro + "%")
                        .DoDataPager<Persona>();
     }


     public Persona GetByGuid(string guid)
     {
         var hql = "from Persona where Guid = :guid";
         var query = Session.CreateQuery(hql);
         query.SetAnsiString("guid", guid);
         return query.UniqueResult<Persona>();
     }


     public IList<Persona> GetAntiguosNoDestinados(int numAntiguedad, int gestionId, DateTime FechaEgreso, int armaId)
     {
         string sql = @"declare @armaId int = :armaId,
		                        @gestionId int = :gestionId,
		                        @numAntiguedad int = :numAntiguedad,
		                        @FechaEgreso datetime = :FechaEgreso


                        select dp.*, p.* from Persona p
                        inner join DUA_Persona dp on dp.PersonaId = p.PersonaId
                        inner join PersonaArma pa on pa.PersonaId = p.PersonaId
                        inner join Arma a on a.ArmaId = pa.ArmaId
                        where a.ArmaId = @armaId AND p.FechaEgreso = @FechaEgreso and 
		                        p.PersonaId not in (select tda.PersonaId from DestinoAsignado tda 
							                        inner join PersonaArma tpa on tpa.PersonaId = tda.PersonaId 
							                        where tda.GestionId = @gestionId and tpa.ArmaId = @armaId)
		                        AND p.NumAntiguedadEgreso < @numAntiguedad
                                order by p.NumAntiguedadEgreso";

         var query = Session.CreateSQLQuery(sql).AddEntity(typeof(Persona));
         query.SetInt32("numAntiguedad", numAntiguedad);
         query.SetInt32("gestionId", gestionId);
         query.SetDateTime("FechaEgreso", FechaEgreso);
         query.SetInt32("armaId", armaId);
         return query.List<Persona>();
     }


     public IList<Persona> GetAntiguosNoDestinados(int numAntiguedad, int gestionId, DateTime FechaEgreso, int armaId, int rolId)
     {
         string sql = @"declare @armaId int = :armaId,
		                        @gestionId int = :gestionId,
		                        @numAntiguedad int = :numAntiguedad,
		                        @FechaEgreso datetime = :FechaEgreso,
                                @RolId	int	= :rolId


                        select dp.*, p.* from Persona p
                        inner join DUA_Persona dp on dp.PersonaId = p.PersonaId
                        inner join DUA_Usuario du on du.PersonaId = dp.PersonaId
                        inner join PersonaArma pa on pa.PersonaId = p.PersonaId
                        inner join HistorialAscenso ha on ha.PersonaId = p.PersonaId
                        inner join Arma a on a.ArmaId = pa.ArmaId
                        where a.ArmaId = @armaId AND p.FechaEgreso = @FechaEgreso and 
                                p.PersonaId not in (select tda.PersonaId from DestinoAsignado tda 
	                                                inner join PersonaArma tpa on tpa.PersonaId = tda.PersonaId 
	                                                where tda.GestionId = @gestionId and tpa.ArmaId = @armaId)
                                AND ha.NumAntiguedadArma < @numAntiguedad
                                and du.RolId = @RolId
                                order by ha.NumAntiguedadArma";

         var query = Session.CreateSQLQuery(sql).AddEntity(typeof(Persona));
         query.SetInt32("numAntiguedad", numAntiguedad);
         query.SetInt32("gestionId", gestionId);
         query.SetDateTime("FechaEgreso", FechaEgreso);
         query.SetInt32("armaId", armaId);
         query.SetInt32("rolId", rolId);
         return query.List<Persona>();
     }


       #region reporte usuario

     public IList<DTORolUsuario> GetRolUsuarios(List<int> rolIds)
     {
         string sql = @" exec siodge_reporte_usuarios  :rolIds";

         var query = Session.CreateSQLQuery(sql);


         if (rolIds != null && rolIds.Count > 0)
             query.SetAnsiString("rolIds", string.Join(",", rolIds));
         else
             query.SetAnsiString("rolIds", string.Empty);

         return query.ListBeanTransformer<DTORolUsuario>();

     
     }

       #endregion


   }
}

